Skip to content

Method: static {...}

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.owlapi;
19:
20: import cz.cvut.kbss.ontodriver.model.Assertion;
21: import cz.cvut.kbss.ontodriver.model.Axiom;
22: import cz.cvut.kbss.ontodriver.model.NamedResource;
23: import cz.cvut.kbss.ontodriver.owlapi.connector.OntologySnapshot;
24: import cz.cvut.kbss.ontodriver.owlapi.util.OwlapiUtils;
25: import org.semanticweb.owlapi.model.*;
26: import org.semanticweb.owlapi.search.EntitySearcher;
27:
28: import java.net.URI;
29: import java.util.*;
30: import java.util.stream.Collectors;
31:
32: class ExplicitAxiomLoader implements AxiomLoader {
33:
34: private static final Assertion UNSPECIFIED_ASSERTION = Assertion.createUnspecifiedPropertyAssertion(false);
35:
36: private final OWLOntology ontology;
37: private final OWLDataFactory dataFactory;
38:
39: private final OwlapiAdapter adapter;
40: private final AxiomAdapter axiomAdapter;
41:
42: private Map<URI, Assertion> assertionMap;
43:
44: ExplicitAxiomLoader(OwlapiAdapter adapter, OntologySnapshot snapshot) {
45: this.adapter = adapter;
46: this.ontology = snapshot.getOntology();
47: this.dataFactory = snapshot.getDataFactory();
48: this.axiomAdapter = new AxiomAdapter(dataFactory);
49: }
50:
51: @Override
52: public Collection<Axiom<?>> loadAxioms(NamedResource subject, Set<Assertion> assertions) {
53: this.assertionMap = new HashMap<>(assertions.size());
54: assertions.forEach(a -> assertionMap.put(a.getIdentifier(), a));
55: final OWLNamedIndividual individual = OwlapiUtils.getIndividual(subject, dataFactory);
56: final Collection<Axiom<?>> axioms = new ArrayList<>();
57: if (assertions.contains(Assertion.createClassAssertion(false))) {
58: axioms.addAll(adapter.getTypesHandler().getTypes(subject, null, false));
59: }
60: axioms.addAll(loadDataPropertyAxioms(individual, subject, false));
61: axioms.addAll(loadObjectPropertyAxioms(individual, subject, false));
62: axioms.addAll(loadAnnotationPropertyAxioms(individual, subject, false));
63: return axioms;
64: }
65:
66: private Collection<Axiom<?>> loadDataPropertyAxioms(OWLNamedIndividual individual, NamedResource subject,
67: boolean loadAll) {
68: final Collection<Axiom<?>> axioms = new ArrayList<>();
69: EntitySearcher.getDataPropertyValues(individual, ontology.importsClosure()).forEach((dp, value) -> {
70: if (loadAll || shouldLoadDataPropertyValue(dp, value)) {
71: axioms.add(axiomAdapter.toAxiom(subject, dp, value));
72: }
73: });
74: return axioms;
75: }
76:
77: private boolean shouldLoadDataPropertyValue(OWLDataPropertyExpression dp, OWLLiteral value) {
78: final IRI dpIri = dp.asOWLDataProperty().getIRI();
79: final Optional<Assertion> assertion = assertionForAxiom(dpIri);
80: return assertion.isPresent() && OwlapiUtils.doesLanguageMatch(value, assertion.get());
81: }
82:
83: private Optional<Assertion> assertionForAxiom(IRI propertyIri) {
84: if (!doesPropertyExist(propertyIri)) {
85: return Optional.empty();
86: }
87: final URI dpUri = propertyIri.toURI();
88: // Note: I don't really like the fact that we are basing this on a randomly generated identifier of the unspecified
89: // property. Perhaps the strategy of using unspecified properties should be revisited.
90: return Optional.of(assertionMap.containsKey(dpUri) ? assertionMap.get(dpUri) :
91: assertionMap.get(UNSPECIFIED_ASSERTION.getIdentifier()));
92: }
93:
94: private boolean doesPropertyExist(IRI o) {
95: return assertionMap.containsKey(o.toURI()) || assertionMap.containsKey(UNSPECIFIED_ASSERTION.getIdentifier());
96: }
97:
98: private Collection<Axiom<?>> loadObjectPropertyAxioms(OWLNamedIndividual individual, NamedResource subject, boolean loadAll) {
99: final Collection<Axiom<?>> axioms = new ArrayList<>();
100: EntitySearcher.getObjectPropertyValues(individual, ontology.importsClosure())
101: .forEach((op, value) -> {
102: if (loadAll || doesPropertyExist(op.getNamedProperty().getIRI())) {
103: axioms.add(axiomAdapter.toAxiom(subject, op, value));
104: }
105: });
106: return axioms;
107: }
108:
109: private Collection<Axiom<?>> loadAnnotationPropertyAxioms(OWLNamedIndividual individual, NamedResource subject,
110: boolean loadAll) {
111: return ontology.importsClosure().flatMap(
112: onto -> EntitySearcher.getAnnotationAssertionAxioms(individual.getIRI(), onto)
113: .filter(a -> loadAll || shouldLoadAnnotationPropertyValue(a)))
114: .map(axiom -> axiomAdapter.toAxiom(subject, axiom)).collect(
115: Collectors.toSet());
116: }
117:
118:
119: private boolean shouldLoadAnnotationPropertyValue(OWLAnnotationAssertionAxiom axiom) {
120: final OWLAnnotationValue value = axiom.getValue();
121: final IRI apIri = axiom.getProperty().asOWLAnnotationProperty().getIRI();
122: final Optional<Assertion> assertion = assertionForAxiom(apIri);
123: return assertion.isPresent() && (value.asLiteral().isEmpty() ||
124: OwlapiUtils.doesLanguageMatch(value.asLiteral().get(), assertion.get()));
125: }
126:
127: @Override
128: public Collection<Axiom<?>> loadPropertyAxioms(NamedResource subject) {
129: final OWLNamedIndividual individual = OwlapiUtils.getIndividual(subject, dataFactory);
130: final Collection<Axiom<?>> axioms = new ArrayList<>(loadDataPropertyAxioms(individual, subject, true));
131: axioms.addAll(loadObjectPropertyAxioms(individual, subject, true));
132: axioms.addAll(loadAnnotationPropertyAxioms(individual, subject, true));
133: return axioms;
134: }
135: }